#ifndef _MSQ_H
#define _MSQ_H

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/sem.h>

#define size 1024						//消息正文的最大长度
#define RECVTYPE_ALL	0 		//接收消息的类型
#define SENDTYPE_A 		0x11	//发送消息的类型
#define SENDTYPE_B 		0x22	//发送消息的类型

/*定义结构体、共用体*/
struct msgbuf 
{									
	long mtype;	 //消息类型 必须大于0						
	char mtext[size]; //消息的内容							
	int pid; //发送消息的进程号							
};	

union semun {
    int              val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                (Linux-specific) */
};


/*全局变量*/


/*函数声明*/

//只针对一个信号量的初始化
#if 0
void sem_init(int sem_id, int value)
{
	union semun sem; //创建共用体对象
	sem.val = value; //value=0,1

	//修改编号0的信号灯的值,值是由sem来设置的
	if (semctl(sem_id, 0, SETVAL, sem)<0) { //sem对象写到信号灯集数组中第0个元素中
		perror("semctl");
		exit(1);
	}
}
#else

//信号灯初始化  ,num表示信号量的编号,也就是信号量集中数组的下标
void sem_init(int sem_id, int num, int value)
{
	union semun sem; //创建共用体对象
	sem.val = value; //value=0,1

	//修改编号num的信号灯的值,值是由sem来设置的
	if (semctl(sem_id, num, SETVAL, sem)<0) { //sem对象写到信号灯集数组中第0个元素中
		perror("semctl");
		exit(1);
	}
}
#endif

//删除信号量IPC对象
void sem_remove(int sem_id)
{
	if (semctl(sem_id, 0, IPC_RMID, NULL)<0) {
		perror("semctl");
		exit(1);
	}
}

//P操作
void sem_p(int sem_id, int num)
{
	struct sembuf sp = {num, -1, 0}; //num信号灯编号,-1分配资源p操作,0阻塞
	if (semop(sem_id, &sp, 1)<0) {
		perror("semop");
		exit(1);
	}
}

//V操作
void sem_v(int sem_id, int num)
{
	struct sembuf sp = {num, 1, 0}; //num信号灯编号,1释放资源v操作,0阻塞
	if (semop(sem_id, &sp, 1)<0) {
		perror("semop");
		exit(1);
	}
}


#endif

